package org.yaac.server.egql.evaluator.function;

import org.yaac.server.egql.evaluator.EvaluationResult;
import org.yaac.server.egql.exception.EGQLException;
import org.yaac.server.egql.processor.ProcessData.ProcessDataRecord;
import org.yaac.shared.ErrorCode;

/**
 * @author Max Zhu (thebbsky@gmail.com)
 *
 */
public class MidFunction extends Function {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	@Override
	public void validate() throws EGQLException {
		FunctionUtil.ensureParamSize(ops, 2, 3);
	}

	@Override
	public EvaluationResult evaluate(ProcessDataRecord record) {
		if (ops.isEmpty()) {
			return new EvaluationResult(null).withWarning(ErrorCode.W111);
		} else if (ops.size() == 2) {
			EvaluationResult val = ops.get(0).evaluate(record);
			EvaluationResult start = ops.get(1).evaluate(record);
			
			if (val.getPayload() instanceof String && start.getPayload() instanceof Number) {
				String str = (String) val.getPayload();
				int startI = ((Number)start.getPayload()).intValue();
				return new EvaluationResult(str.substring(startI), val, start);
			} else {
				return val.withWarning(ErrorCode.W110);
			}
		} else if (ops.size() == 3) {
			EvaluationResult val = ops.get(0).evaluate(record);
			EvaluationResult start = ops.get(1).evaluate(record);
			EvaluationResult length = ops.get(2).evaluate(record);
			
			if (val.getPayload() instanceof String && 
					start.getPayload() instanceof Number && 
					length.getPayload() instanceof Number) {
				String str = (String) val.getPayload();
				int startI = ((Number)start.getPayload()).intValue();
				int lengthI = ((Number)length.getPayload()).intValue();
				return new EvaluationResult(str.substring(startI, startI + lengthI), val, start, length);
			} else {
				return val.withWarning(ErrorCode.W110);
			}
		} else {
			return ops.get(0).evaluate(record).withWarning(ErrorCode.W111);
		}
	}

}
